home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / newcpu.c < prev    next >
C/C++ Source or Header  |  1996-05-12  |  15KB  |  656 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * MC68000 emulation
  5.   *
  6.   * (c) 1995 Bernd Schmidt
  7.   */
  8.  
  9. #include "sysconfig.h"
  10. #include "sysdeps.h"
  11.  
  12. #include "config.h"
  13. #include "options.h"
  14. #include "events.h"
  15. #include "gui.h"
  16. #include "memory.h"
  17. #include "custom.h"
  18. #include "newcpu.h"
  19. #include "ersatz.h"
  20. #include "readcpu.h"
  21.  
  22. int areg_byteinc[] = { 1,1,1,1,1,1,1,2 };
  23. int imm8_table[] = { 8,1,2,3,4,5,6,7 };
  24.  
  25. cpuop_func *cpufunctbl[65536];
  26.  
  27. #ifdef COUNT_INSTRS
  28. static unsigned long int instrcount[65536];
  29. static UWORD opcodenums[65536];
  30.  
  31. int compfn(const void *el1, const void *el2)
  32. {
  33.     return instrcount[*(const UWORD *)el1] < instrcount[*(const UWORD *)el2];
  34. }
  35.  
  36. void dump_counts(void)
  37. {
  38.     FILE *f = fopen("insncount", "w");
  39.     unsigned long int total = 0;
  40.     int i;
  41.     
  42.     for(i=0; i < 65536; i++) {
  43.     opcodenums[i] = i;
  44.         total += instrcount[i];
  45.     }
  46.     qsort(opcodenums, 65536, sizeof(UWORD), compfn);
  47.     
  48.     fprintf(f, "Total: %ld\n", total);
  49.     for(i=0; i < 65536; i++) {
  50.     unsigned long int cnt = instrcount[opcodenums[i]];
  51.     if (!cnt)
  52.         break;
  53.     fprintf(f, "%04x: %ld\n", opcodenums[i], cnt);
  54.     }
  55.     fclose(f);
  56. }
  57. #endif
  58.  
  59. int broken_in;
  60.  
  61. #ifdef INTEL_FLAG_OPT
  62. union flagu intel_flag_lookup[256];
  63. #endif
  64.  
  65. void init_m68k (void)
  66. {
  67.     long int opcode;
  68.     int i;
  69.     
  70. #ifdef COUNT_INSTRS
  71.     memset(instrcount, 0, sizeof instrcount);
  72. #endif
  73. #ifdef INTEL_FLAG_OPT
  74.     for (i = 0; i < 256; i++) {
  75.     intel_flag_lookup[i].flags.c = !!(i & 1);
  76.     intel_flag_lookup[i].flags.z = !!(i & 64);
  77.     intel_flag_lookup[i].flags.n = !!(i & 128);
  78.     intel_flag_lookup[i].flags.v = 0;
  79.     }
  80. #endif
  81.     printf("Building CPU table...\n");
  82.     read_table68k ();
  83.     do_merges ();
  84.     for (opcode = 0; opcode < 65536; opcode++)
  85.     cpufunctbl[opcode] = op_illg;
  86.     for (i = 0; smallcputbl[i].handler != NULL; i++) {
  87.     if (!smallcputbl[i].specific)
  88.         cpufunctbl[smallcputbl[i].opcode] = smallcputbl[i].handler;
  89.     }
  90.     for (opcode = 0; opcode < 65536; opcode++) {
  91.     cpuop_func *f;
  92.     
  93.     if (table68k[opcode].mnemo == i_ILLG)
  94.         continue;
  95.     
  96.     if (table68k[opcode].handler != -1) {
  97.         f = cpufunctbl[table68k[opcode].handler];
  98.         if (f == op_illg)
  99.         abort();
  100.         cpufunctbl[opcode] = f;
  101.     }
  102.     }    
  103.     for (i = 0; smallcputbl[i].handler != NULL; i++) {
  104.     if (smallcputbl[i].specific)
  105.         cpufunctbl[smallcputbl[i].opcode] = smallcputbl[i].handler;
  106.     }
  107. }
  108.  
  109. struct regstruct regs;
  110. union flagu regflags;
  111. static void ShowEA(int reg, amodes mode, wordsizes size)
  112. {
  113.     UWORD dp;
  114.     BYTE disp8;
  115.     WORD disp16;
  116.     int r;
  117.     ULONG dispreg;
  118.     CPTR addr;
  119.     
  120.     switch(mode){
  121.      case Dreg:
  122.     printf("D%d", reg);
  123.     break;
  124.      case Areg:
  125.     printf("A%d", reg);
  126.     break;
  127.      case Aind:
  128.     printf("(A%d)", reg);
  129.     break;
  130.      case Aipi:
  131.     printf("(A%d)+", reg);
  132.     break;
  133.      case Apdi:
  134.     printf("-(A%d)", reg);
  135.     break;
  136.      case Ad16:
  137.     disp16 = nextiword();
  138.     addr = regs.a[reg] + (WORD)disp16;
  139.     printf("(A%d,$%04lx) == $%08lx", reg, disp16, (long unsigned int)addr);
  140.     break;
  141.      case Ad8r:
  142.     dp = nextiword();
  143.     disp8 = dp & 0xFF;
  144.     r = (dp & 0x7000) >> 12;
  145.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];    
  146.     if (!(dp & 0x800)) dispreg = (LONG)(WORD)(dispreg);
  147.     
  148.     addr = regs.a[reg] + disp8 + dispreg;
  149.     printf("(A%d, %c%d.%c, $%02x) == $%08lx", reg, 
  150.            dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W', disp8,
  151.            (long unsigned int)addr);
  152.     break;
  153.      case PC16:
  154.     addr = m68k_getpc();
  155.     disp16 = nextiword();
  156.     addr += (WORD)disp16;
  157.     printf("(PC,$%08lx) == $%08lx", disp16, (long unsigned int)addr);
  158.     break;
  159.      case PC8r:
  160.     addr = m68k_getpc();
  161.     dp = nextiword();
  162.     disp8 = dp & 0xFF;
  163.     r = (dp & 0x7000) >> 12;
  164.     dispreg = dp & 0x8000 ? regs.a[r] : regs.d[r];
  165.     
  166.     if (!(dp & 0x800)) dispreg = (LONG)(WORD)(dispreg);
  167.     addr += disp8 + dispreg;
  168.     printf("(PC, %c%d.%c, $%02x) == $%08lx", dp & 0x8000 ? 'A' : 'D', 
  169.            (int)r, dp & 0x800 ? 'L' : 'W', disp8, (long unsigned int)addr);
  170.     break;
  171.      case absw:
  172.     printf("$%08lx", (LONG)(WORD)nextiword());
  173.     break;
  174.      case absl:
  175.     printf("$%08lx", nextilong());
  176.     break;
  177.      case imm:
  178.     switch(size){
  179.      case sz_byte:
  180.         printf("#$%02x", nextiword() & 0xff); break;
  181.      case sz_word:
  182.         printf("#$%04x", nextiword()); break;
  183.      case sz_long:
  184.         printf("#$%08lx", nextilong()); break;
  185.      default:
  186.         abort();
  187.     }
  188.     break;
  189.      case imm0:
  190.     printf("#$%02lx", nextiword() & 0xff);
  191.     break;
  192.      case imm1:
  193.     printf("#$%04lx", nextiword());
  194.     break;
  195.      case imm2:
  196.     printf("#$%08lx", nextilong());
  197.     break;
  198.      case immi:
  199.     printf("#$%04lx", reg);
  200.     break;
  201.      default:
  202.     abort();
  203.     }
  204. }
  205.  
  206. #if CPU_LEVEL > 1
  207. ULONG get_disp_ea (ULONG base, UWORD dp)
  208. {
  209.     int reg = (dp >> 12) & 7;
  210.     LONG regd;
  211.     if (dp & 0x8000)
  212.     regd = regs.a[reg];
  213.     else
  214.     regd = regs.d[reg];
  215.     if (!(dp & 0x800))
  216.     regd = (LONG)(WORD)regd;
  217.     if (dp & 0x100) {
  218.     LONG extraind = 0;
  219.     printf("020\n");
  220.     regd <<= (dp >> 9) & 3;
  221.     if (dp & 0x80)
  222.         base = 0;
  223.     if (dp & 0x40)
  224.         regd = 0;
  225.     if ((dp & 0x30) == 0x20)
  226.         base += (LONG)(WORD)nextiword();
  227.     if ((dp & 0x30) == 0x30)
  228.         base += nextilong();
  229.     
  230.     if ((dp & 0x3) == 0x2)
  231.         extraind = (LONG)(WORD)nextiword();
  232.     if ((dp & 0x3) == 0x3)
  233.         extraind = nextilong();
  234.     
  235.     if (!(dp & 4))
  236.         base += regd;
  237.     if (dp & 3)
  238.         base = get_long (base);
  239.     if (dp & 4)
  240.         base += regd;
  241.     
  242.     return base + extraind;
  243.     /* Yikes, that's complicated */
  244.     } else {
  245.     return base + (BYTE)(dp) + regd;
  246.     }
  247. }
  248. #endif
  249.  
  250. void MakeSR(void)
  251. {
  252. #if 0
  253.     assert((NFLG & 1) == NFLG);
  254.     assert((regs.s & 1) == regs.s);
  255.     assert((regs.x & 1) == regs.x);
  256.     assert((CFLG & 1) == CFLG);
  257.     assert((VFLG & 1) == VFLG);
  258.     assert((ZFLG & 1) == ZFLG);
  259. #endif
  260.     regs.sr = ((regs.t << 15) | (regs.s << 13) | (regs.intmask << 8)
  261.            | (regs.x << 4) | (NFLG << 3) | (ZFLG << 2) | (VFLG << 1) 
  262.            |  CFLG);
  263. }
  264.  
  265. void MakeFromSR(void)
  266. {
  267.     int olds = regs.s;
  268.  
  269.     regs.t = (regs.sr >> 15) & 1;
  270.     regs.s = (regs.sr >> 13) & 1;
  271.     regs.intmask = (regs.sr >> 8) & 7;
  272.     regs.x = (regs.sr >> 4) & 1;
  273.     NFLG = (regs.sr >> 3) & 1;
  274.     ZFLG = (regs.sr >> 2) & 1;
  275.     VFLG = (regs.sr >> 1) & 1;
  276.     CFLG = regs.sr & 1;
  277.     if (olds != regs.s) {
  278.     CPTR temp = regs.usp;
  279.     regs.usp = regs.a[7];
  280.     regs.a[7] = temp;
  281.     }
  282.     specialflags |= SPCFLAG_INT;
  283.     if (regs.t)
  284.         specialflags |= SPCFLAG_TRACE;
  285.     else
  286.         specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
  287. }
  288.  
  289. void Exception(int nr)
  290. {
  291.     MakeSR();
  292.     if (!regs.s) {
  293.     CPTR temp = regs.usp;
  294.     regs.usp = regs.a[7];
  295.     regs.a[7] = temp;
  296.     regs.s = 1;
  297.     }
  298.     if (CPU_LEVEL > 0) {
  299.     regs.a[7] -= 2;
  300.     put_word (regs.a[7], nr * 4);
  301.     }
  302.     regs.a[7] -= 4;
  303.     put_long (regs.a[7], m68k_getpc ());
  304.     regs.a[7] -= 2;
  305.     put_word (regs.a[7], regs.sr);
  306.     m68k_setpc(get_long(regs.vbr + 4*nr));
  307.     regs.t = 0;
  308.     specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);
  309. }
  310.  
  311. static void Interrupt(int nr)
  312. {
  313.     assert(nr < 8 && nr >= 0);
  314.     Exception(nr+24);
  315.     
  316.     regs.intmask = nr;
  317.     specialflags |= SPCFLAG_INT;
  318. }
  319.  
  320. static int caar, cacr;
  321.  
  322. void m68k_move2c (int regno, ULONG *regp)
  323. {
  324.     if (CPU_LEVEL == 1 && (regno & 0x7FF) > 1)
  325.     op_illg (0x4E7B);
  326.     else
  327.     switch (regno) {
  328.      case 0: regs.sfc = *regp; break;
  329.      case 1: regs.dfc = *regp; break;
  330.      case 2: cacr = *regp & 0xFF; break;
  331.      case 0x800: regs.usp = *regp; break;
  332.      case 0x801: regs.vbr = *regp; break;
  333.      case 0x802: caar = *regp & 0xFF; break;
  334.      default:
  335.         op_illg (0x4E7B);
  336.         break;
  337.     }
  338. }
  339.  
  340. void m68k_movec2 (int regno, ULONG *regp)
  341. {
  342.     if (CPU_LEVEL == 1 && (regno & 0x7FF) > 1)
  343.     op_illg (0x4E7A);
  344.     else
  345.     switch (regno) {
  346.      case 0: *regp = regs.sfc; break;
  347.      case 1: *regp = regs.dfc; break;
  348.      case 2: *regp = cacr; break;
  349.      case 0x800: *regp = regs.usp; break;
  350.      case 0x801: *regp = regs.vbr; break;
  351.      case 0x802: *regp = caar; break;
  352.      default:
  353.         op_illg (0x4E7A);
  354.         break;
  355.     }
  356. }
  357.  
  358. extern void m68k_divl (UWORD opcode, ULONG src, UWORD extra)
  359. {
  360.     if (src == 0)
  361.     return;
  362. #ifdef INT_64BIT
  363.     if (extra & 0x800) {
  364.     /* signed variant */
  365.     INT_64BIT a = regs.d[(extra >> 12) & 7];
  366.     INT_64BIT quot, rem;
  367.     
  368.     if (extra & 0x400)
  369.         a |= (INT_64BIT)regs.d[extra & 7] << 32;
  370.     rem = a % src;
  371.     quot = a / src;
  372.     if ((extra & 0x400) && (extra & 7) != ((extra >> 12) & 7))
  373.         regs.d[extra & 7] = rem;
  374.     regs.d[(extra >> 12) & 7] = quot;
  375.     } else {
  376.     /* unsigned */
  377.     unsigned INT_64BIT a = regs.d[(extra >> 12) & 7];
  378.     unsigned INT_64BIT quot, rem;
  379.     
  380.     if (extra & 0x400)
  381.         a |= (INT_64BIT)regs.d[extra & 7] << 32;
  382.     rem = a % src;
  383.     quot = a / src;
  384.     if ((extra & 0x400) && (extra & 7) != ((extra >> 12) & 7))
  385.         regs.d[extra & 7] = rem;
  386.     regs.d[(extra >> 12) & 7] = quot;
  387.     }
  388. #endif
  389. }
  390.  
  391. extern void m68k_mull (UWORD opcode, ULONG src, UWORD extra)
  392. {
  393. #ifdef INT_64BIT
  394.     if (extra & 0x800) {
  395.     /* signed variant */
  396.     INT_64BIT a = (LONG)regs.d[(extra >> 12) & 7];
  397.  
  398.     a *= (LONG)src;
  399.     if ((extra & 0x400) && (extra & 7) != ((extra >> 12) & 7))
  400.         regs.d[extra & 7] = a >> 32;
  401.     regs.d[(extra >> 12) & 7] = (ULONG)a;
  402.     } else {
  403.     /* unsigned */
  404.     unsigned INT_64BIT a = (ULONG)regs.d[(extra >> 12) & 7];
  405.     unsigned INT_64BIT quot, rem;
  406.     
  407.     a *= src;
  408.     if ((extra & 0x400) && (extra & 7) != ((extra >> 12) & 7))
  409.         regs.d[extra & 7] = a >> 32;
  410.     regs.d[(extra >> 12) & 7] = (ULONG)a;
  411.     }
  412. #endif
  413. }
  414.  
  415. static char* ccnames[] =
  416. { "T ","F ","HI","LS","CC","CS","NE","EQ",
  417.   "VC","VS","PL","MI","GE","LT","GT","LE" };
  418.  
  419. void MC68000_reset(void)
  420. {
  421.     regs.a[7] = get_long(0x00f80000);
  422.     m68k_setpc(get_long(0x00f80004));
  423.     regs.s = 1;
  424.     regs.stopped = 0;
  425.     regs.t = 0;
  426.     specialflags = 0;
  427.     regs.intmask = 7;
  428.     regs.vbr = regs.sfc = regs.dfc = 0;
  429.     customreset();
  430. }
  431.  
  432. void op_illg(ULONG opcode)
  433. {
  434.     if (opcode == 0x4E7B && get_long(0x10) == 0 
  435.     && (m68k_getpc() & 0xF80000) == 0xF80000) 
  436.     {
  437.     fprintf(stderr, "Your Kickstart requires a 68020 CPU. Giving up.\n");
  438.     broken_in = 1; 
  439.     specialflags |= SPCFLAG_BRK;
  440.     quit_program = 1;
  441.     }
  442.     if (opcode == 0xF00D && ((m68k_getpc() & 0xF80000) == 0xF80000)) {
  443.     /* This is from the dummy Kickstart replacement */
  444.     ersatz_perform (nextiword ());
  445.     return;
  446.     }
  447.     regs.pc_p--;
  448.     if ((opcode & 0xF000) == 0xF000) {
  449.     if ((opcode & 0xE00) == 0x200)
  450.         Exception(0xB);
  451.     else 
  452.         switch (opcode & 0x1FF) {
  453.          case 0x17:
  454.         regs.pc_p+=2;
  455.         break;
  456.          default:
  457.         regs.pc_p++;
  458.         }
  459.     return;
  460.     }
  461.     if ((opcode & 0xF000) == 0xA000) {
  462.         Exception(0xA);
  463.     return;
  464.     }
  465.     fprintf(stderr, "Illegal instruction: %04x\n", opcode);
  466.     Exception(4);
  467. }
  468.  
  469. static int n_insns=0, n_spcinsns=0;
  470.  
  471. static __inline__ void do_hardware(void)
  472. {
  473.     if (specialflags & SPCFLAG_BLIT) {
  474.     do_blitter();
  475. #ifdef NO_FAST_BLITTER
  476.     do_blitter();
  477.     do_blitter();
  478.     do_blitter();
  479. #endif
  480.     }
  481.     if (specialflags & SPCFLAG_DISK) {
  482.     do_disk(); /* This is not critical. Four calls make disk */
  483.     do_disk(); /* loading quite fast. */
  484.     do_disk();
  485.     do_disk();
  486.     }
  487. }
  488.  
  489. void MC68000_run(void)
  490. {
  491.     for(;;) {
  492.     UWORD opcode;
  493.     /* assert (!regs.stopped && !(specialflags & SPCFLAG_STOP)); */
  494.     opcode = nextiword();
  495. #ifdef COUNT_INSTRS
  496.     instrcount[opcode]++;
  497. #endif
  498.     (*cpufunctbl[opcode])(opcode);
  499. #ifndef NO_EXCEPTION_3
  500.     if (buserr) {
  501.         Exception(3);
  502.         buserr = 0;
  503.     }
  504. #endif
  505.     /*n_insns++;*/
  506.     do_cycles();    
  507.     if (specialflags) {
  508.         /*n_spcinsns++;*/
  509.         while (specialflags & SPCFLAG_BLTNASTY) {
  510.         do_cycles();
  511.         do_hardware();
  512.         }
  513.         if (specialflags & SPCFLAG_DOTRACE) {
  514.         Exception(9);
  515.         }
  516.         while (specialflags & SPCFLAG_STOP) {
  517.         do_cycles();
  518.         do_hardware();
  519.         if (specialflags & (SPCFLAG_INT | SPCFLAG_DOINT)){
  520.             int intr = intlev();
  521.             specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  522.             specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  523.             if (intr != -1 && intr > regs.intmask) {
  524.             Interrupt(intr);
  525.             regs.stopped = 0;
  526.             specialflags &= ~SPCFLAG_STOP;
  527.             }        
  528.         }        
  529.         }
  530.         if (specialflags & SPCFLAG_TRACE) {
  531.         specialflags &= ~SPCFLAG_TRACE;
  532.         specialflags |= SPCFLAG_DOTRACE;
  533.         }
  534. #ifdef WANT_SLOW_MULTIPLY
  535.         /* Kludge for Hardwired demo. The guys who wrote it should be
  536.          * mutilated. */
  537.         if (specialflags & SPCFLAG_EXTRA_CYCLES) {
  538.         do_cycles ();
  539.         do_cycles ();
  540.         do_cycles ();
  541.         do_cycles ();
  542.         specialflags &= ~SPCFLAG_EXTRA_CYCLES;
  543.         }
  544. #endif
  545.         do_hardware();
  546.         
  547.         if (specialflags & SPCFLAG_DOINT) {
  548.         int intr = intlev();
  549.         specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);
  550.         if (intr != -1 && intr > regs.intmask) {
  551.             Interrupt(intr);
  552.             regs.stopped = 0;
  553.         }        
  554.         }
  555.         if (specialflags & SPCFLAG_INT) {
  556.         specialflags &= ~SPCFLAG_INT;
  557.         specialflags |= SPCFLAG_DOINT;
  558.         }
  559.         if (specialflags & SPCFLAG_BRK) {        
  560.         specialflags &= ~SPCFLAG_BRK;
  561.         return;        
  562.         }
  563.     }
  564.     }
  565. }
  566.  
  567. void MC68000_step(void)
  568. {
  569.     specialflags |= SPCFLAG_BRK;
  570.     MC68000_run();
  571. }
  572.  
  573. void MC68000_skip(CPTR nextpc)
  574. {
  575.     broken_in = 0;
  576.     specialflags |= SPCFLAG_BRK;
  577.     do {
  578.     MC68000_step();
  579.     } while (nextpc != m68k_getpc() && !broken_in);
  580. }
  581.  
  582. void MC68000_disasm(CPTR addr, CPTR *nextpc, int cnt)
  583. {
  584.     CPTR pc = m68k_getpc();
  585.     m68k_setpc(addr);
  586.     for (;cnt--;){
  587.     char instrname[20],*ccpt;
  588.     int opwords;
  589.     UWORD opcode;
  590.     UWORD special = 0;
  591.     struct mnemolookup *lookup;
  592.     struct instr *dp;
  593.     printf("%08lx: ", m68k_getpc());
  594.     for(opwords = 0; opwords < 5; opwords++){
  595.         printf("%04x ", get_word(m68k_getpc() + opwords*2));
  596.     }
  597.     
  598.     opcode = nextiword();
  599.     if (cpufunctbl[opcode] == op_illg) {
  600.         opcode = 0x4AFC;
  601.     }
  602.     dp = table68k + opcode;
  603.     for (lookup = lookuptab;lookup->mnemo != dp->mnemo; lookup++)
  604.         ;
  605.     
  606.     strcpy(instrname,lookup->name);
  607.     ccpt = strstr(instrname,"cc");
  608.     if (ccpt != 0) {
  609.         strncpy(ccpt,ccnames[dp->cc],2);
  610.     }
  611.     printf("%s", instrname);
  612.     switch(dp->size){
  613.      case sz_byte: printf(".B "); break;
  614.      case sz_word: printf(".W "); break;
  615.      case sz_long: printf(".L "); break;
  616.      default: break;
  617.     }
  618.  
  619.     if (dp->suse) {
  620.         ShowEA(dp->sreg, dp->smode, dp->size);
  621.     }
  622.     if (dp->suse && dp->duse)
  623.         printf(",");
  624.     if (dp->duse) {
  625.         ShowEA(dp->dreg, dp->dmode, dp->size);
  626.     }
  627.     if (ccpt != 0) {
  628.         if (cctrue(dp->cc))
  629.         printf(" (TRUE)");
  630.         else 
  631.         printf(" (FALSE)");
  632.     }
  633.     printf("\n");
  634.     }
  635.     *nextpc = m68k_getpc();
  636.     m68k_setpc(pc);
  637. }
  638.  
  639. void MC68000_dumpstate(CPTR *nextpc)
  640. {
  641.     int i;
  642.     for(i = 0; i < 8; i++){
  643.     printf("D%d: %08lx ", i, regs.d[i]);
  644.     if ((i & 3) == 3) printf("\n");
  645.     }
  646.     for(i=0;i<8;i++){
  647.     printf("A%d: %08lx ", i, regs.a[i]);
  648.     if ((i & 3) == 3) printf("\n");
  649.     }
  650.     printf ("T=%d S=%d X=%d N=%d Z=%d V=%d C=%d IMASK=%d\n", regs.t, regs.s, 
  651.         regs.x, NFLG, ZFLG, VFLG, CFLG, regs.intmask);
  652.     MC68000_disasm(m68k_getpc(), nextpc, 1);
  653.     printf("next PC: %08lx\n", *nextpc);
  654. }
  655.  
  656.